ποΈGitΠ―ΡΠ°ποΈ
Node / meshtastic / Meshtastic-Android / files / docs / en / developer / navigation-and-deep-links.md
docs/en/developer/navigation-and-deep-links.md fix/qr-error-correction (7b45f84f) Text, 6.88 KB
title: Navigation & Deep Links
parent: Developer Guide
nav_order: 4
last_updated: 2026-07-08
aliases:
β’ deeplinks
β’ navigation-3
β’ routes
Navigation & Deep Links
The app uses Navigation 3 with typed, serializable routes and centralized deep link resolution.
Route Architecture
All routes are defined in T383838core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/Routes.kt.
Route Hierarchy
T282828
Tff7b72interface T56d364Route Tb4b4b4: Te6edf3NavKey T8b949e// All routes implement NavKey
Tff7b72interface T56d364Graph Tb4b4b4: Te6edf3Route T8b949e// Graph roots for navigation hierarchies
Tf0883e@Serializable
Tff7b72sealed Tff7b72interface T56d364SettingsRoute Tb4b4b4: Te6edf3Route Tb4b4b4{
Tf0883e@Serializable Tff7b72data Tff7b72class T56d364SettingsTb4b4b4(Tff7b72val Te6edf3destNumTb4b4b4: Tffa657Int? Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4: Te6edf3SettingsRouteTb4b4b4, Te6edf3Graph
Tf0883e@Serializable Tff7b72data Tff7b72object T56d364DeviceConfiguration Tb4b4b4: Te6edf3SettingsRoute
Tf0883e@Serializable Tff7b72data Tff7b72object T56d364HelpDocs Tb4b4b4: Te6edf3SettingsRoute
Tf0883e@Serializable Tff7b72data Tff7b72class T56d364HelpDocPageTb4b4b4(Tff7b72val Te6edf3pageIdTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4: Te6edf3SettingsRoute
T8b949e// ...
Tb4b4b4}
Conventions
β’ Routes are T383838@Serializable for state restoration
β’ Use T383838data object for routes without parameters
β’ Use T383838data class for parameterized routes
β’ Group related routes under a T383838sealed interface
β’ Graph entry points implement both the route interface and T383838Graph
Deep Link Router
T383838DeepLinkRouter in T383838core/navigation maps URI deep links to typed backstack lists.
URI Format
Both forms resolve through the same T383838DeepLinkRouter, so any path below works with either scheme:
T282828
meshtastic://meshtastic/{path}
https://meshtastic.org/{path} # App Link, android:autoVerify β also opens in-app on a real device/adb
T383838adb shell am start -a android.intent.action.VIEW -d "meshtastic://meshtastic/{path}" is the fastest way to
trigger any route below from a shell or automation script without touching the UI.
For the T383838https form to open in-app, each top-level path segment must also be declared as an
T383838android:pathPrefix in the T383838android:autoVerify intent-filter in T383838androidApp/src/main/AndroidManifest.xml β
otherwise the link opens in the browser. Adding a new top-level route therefore takes three steps: add the
segment to T383838DeepLinkRouter.topLevelPathSegments (the router refuses to dispatch segments outside that set),
add its T383838when branch in T383838DeepLinkRouter.route(), and add the matching T383838pathPrefix to the manifest.
T383838DeepLinkManifestConsistencyTest (androidApp unit tests) checks the manifest against the set, so a missing
manifest entry fails CI.
Source of truth: the always-current list of top-level segments is T383838topLevelPathSegments in
β sub-paths live in the T383838route() T383838when block plus its helper maps (T383838settingsSubRoutes, T383838nodeDetailSubRoutes);
the class-level KDoc is illustrative, not exhaustive. It also exists as executable spec in
The table below is a snapshot for quick reference β check those two files if it looks out of date.
Supported Deep Links
ββββββββββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββ¬ββββββ
β URI Path β Route β Noβ¦ β
ββββββββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββββββββββΌββββββ€
β T383838/connections β T383838ConnectionsRoute.Connections(null) β Coβ¦ β
β T383838/connections?address={prefixedAddress} β T383838ConnectionsRoute.Connections(address) β Auβ¦ β
β T383838/connections?address=n β T383838ConnectionsRoute.Connections("n") β Diβ¦ β
β T383838/wifi-provision β T383838WifiProvisionRoute.WifiProvision(null) β Wiβ¦ β
β T383838/wifi-provision?address={mac} β T383838WifiProvisionRoute.WifiProvision(mac) β Prβ¦ β
β T383838/settings β T383838SettingsRoute.Settings(null) β Seβ¦ β
β T383838/settings/helpDocs β T383838SettingsRoute.HelpDocs β Doβ¦ β
β T383838/settings/helpDocs/{pageId} β T383838SettingsRoute.HelpDocPage(pageId) β Spβ¦ β
β T383838/settings/help-docs β T383838SettingsRoute.HelpDocs β Coβ¦ β
β T383838/discovery β T383838DiscoveryRoute.DiscoveryGraph β Loβ¦ β
β T383838/settings/local-mesh-discovery/session/{sesβ¦ β T383838DiscoveryRoute.DiscoverySummary(sessionId) β Diβ¦ β
β T383838/nodes β T383838NodesRoute.Nodes β Noβ¦ β
β T383838/nodes/{destNum} β T383838NodesRoute.NodeDetail(destNum) β Noβ¦ β
β T383838/nodes/{destNum}/{metric} β e.g. T383838NodeDetailRoute.DeviceMetrics(destNum) β Spβ¦ β
β T383838/messages β T383838ContactsRoute.Contacts β Coβ¦ β
β T383838/messages/{contactKey} β T383838ContactsRoute.Messages(contactKey) β Spβ¦ β
β T383838/share?message={text} β T383838ContactsRoute.Share(message) β Shβ¦ β
β T383838/quickchat β T383838ContactsRoute.QuickChat β Quβ¦ β
β T383838/map β T383838MapRoute.Map(null) β Maβ¦ β
β T383838/map/{waypointId} β T383838MapRoute.Map(waypointId) β Maβ¦ β
β T383838/channels β T383838ChannelsRoute.Channels β Chβ¦ β
β T383838/firmware β T383838FirmwareRoute.FirmwareGraph β Fiβ¦ β
β T383838/firmware/update β T383838FirmwareRoute.FirmwareUpdate β Fiβ¦ β
ββββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββββββββββββ΄ββββββ
Backstack Synthesis
Deep links synthesize a full backstack, not just the target screen:
T282828
T8b949e// /settings/helpDocs/messages-and-channels produces:
Te6edf3listOfTb4b4b4(
Te6edf3SettingsRouteTb4b4b4.Te6edf3SettingsTb4b4b4(Tff7b72nullTb4b4b4)Tb4b4b4,
Te6edf3SettingsRouteTb4b4b4.Te6edf3HelpDocsTb4b4b4,
Te6edf3SettingsRouteTb4b4b4.Te6edf3HelpDocPageTb4b4b4(Ta5d6ff"Ta5d6ffmessages-and-channelsTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4)
This ensures the user can navigate "up" correctly.
Adding a Deep Link
1. Define the typed route in T383838Routes.kt.
2. Add the mapping in T383838DeepLinkRouter.settingsSubRoutes (or equivalent for other graphs).
3. Add a test in T383838DeepLinkRouterTest.kt.
4. Register the navigation entry in the appropriate feature module.
5. Update the KDoc list on T383838DeepLinkRouter.route() and the table above β they're the two places tooling/agents look to discover what deep links exist.
Navigation Entry Registration
Each feature module provides entries via an extension function:
T282828
Tff7b72fun Td2a8ffEntryProviderScopeTff7b72<Te6edf3NavKeyTff7b72>Tb4b4b4.Te6edf3docsEntriesTb4b4b4(Te6edf3backStackTb4b4b4: Te6edf3NavBackStackTff7b72<Te6edf3NavKeyTff7b72>Tb4b4b4) Tb4b4b4{
Te6edf3entryTff7b72<Te6edf3SettingsRouteTb4b4b4.Te6edf3HelpDocsTff7b72> Tb4b4b4{ Te6edf3DocsBrowserScreenTb4b4b4(Te6edf3backStackTb4b4b4) Tb4b4b4}
Te6edf3entryTff7b72<Te6edf3SettingsRouteTb4b4b4.Te6edf3HelpDocPageTff7b72> Tb4b4b4{ Te6edf3route Tff7b72-Tff7b72> Te6edf3DocsPageRouteScreenTb4b4b4(Te6edf3routeTb4b4b4.Te6edf3pageIdTb4b4b4, Te6edf3backStackTb4b4b4) Tb4b4b4}
Tb4b4b4}
These are called from the settings navigation composition.
Testing
Deep link routing is tested in:
T282828
core/navigation/src/commonTest/kotlin/org/meshtastic/core/navigation/DeepLinkRouterTest.kt
Served by rngit 1.5.0 - Generated in 0.09s